/* * Author: Chris Seguin * * This software has been developed under the copyleft * rules of the GNU General Public License. Please * consult the GNU General Public License for more * details about use and distribution of this software. */ package org.acm.seguin.summary; import org.acm.seguin.parser.Node; import org.acm.seguin.parser.ast.ASTName; import org.acm.seguin.parser.ast.ASTPrimitiveType; import org.acm.seguin.parser.ast.ASTResultType; import org.acm.seguin.parser.ast.ASTType; import org.acm.seguin.summary.query.GetTypeSummary; /** * Summarize a type declaration. This object is meant to store the name and * package of some type. This will be used in variable summaries, as well as * for return values and exceptions. * *@author Chris Seguin *@created May 11, 1999 */ public class TypeDeclSummary extends Summary { // Instance Variables private String typeName; private String packageName; private boolean primitive; private int arrayCount; /** * Creates a type declaration summary. * *@param parentSummary the parent summary */ public TypeDeclSummary(Summary parentSummary) { // Initialize the parent class super(parentSummary); // Remember the type name typeName = "void".intern(); // The package name doesn't apply packageName = null; // This is a primitive value primitive = true; // This isn't an array (yet) arrayCount = 0; } /** * Creates a type declaration summary from an ASTName object. * *@param parentSummary the parent summary *@param nameNode the ASTName object */ public TypeDeclSummary(Summary parentSummary, ASTName nameNode) { // Initialize the parent class super(parentSummary); // Local Variables int numChildren = nameNode.getNameSize(); // Determine the name type typeName = nameNode.getNamePart(numChildren - 1).intern(); // Extract the package if (numChildren > 1) { StringBuffer buffer = new StringBuffer(nameNode.getNamePart(0)); for (int ndx = 1; ndx < numChildren - 1; ndx++) { buffer.append("."); buffer.append(nameNode.getNamePart(ndx)); } packageName = buffer.toString().intern(); } else { packageName = null; } // This isn't a primitive value primitive = false; // This isn't an array (yet) arrayCount = 0; } /** * Creates a type declaration summary from an ASTPrimitiveType object. * *@param parentSummary the parent summary *@param primitiveType the ASTPrimitiveType object */ public TypeDeclSummary(Summary parentSummary, ASTPrimitiveType primitiveType) { // Initialize the parent class super(parentSummary); // Remember the type name typeName = primitiveType.getName().intern(); // The package name doesn't apply packageName = null; // This is a primitive value primitive = true; // This isn't an array (yet) arrayCount = 0; } /** * Creates a type declaration summary from an ASTName object. * *@param parentSummary the parent summary *@param initPackage the package name *@param initType the type name */ public TypeDeclSummary(Summary parentSummary, String initPackage, String initType) { super(parentSummary); typeName = initType; packageName = initPackage; primitive = false; arrayCount = 0; } /** * Set the array count * *@param count the number of "[]" pairs */ public void setArrayCount(int count) { if (count >= 0) { arrayCount = count; } } /** * Return the number of "[]" pairs * *@return the array count */ public int getArrayCount() { return arrayCount; } /** * Is this an array? * *@return true if this is an array */ public boolean isArray() { return (arrayCount > 0); } /** * Get the package name * *@return a string containing the name of the package */ public String getPackage() { return packageName; } /** * Get the name of the type * *@return a string containing the name of the type */ public String getType() { return typeName; } /** * Check if this is a primitive node * *@return true if this is a primitive value */ public boolean isPrimitive() { return primitive; } /** * Get long name * *@return the long version of the name (type + package) */ public String getLongName() { if (packageName == null) { return typeName; } else { return packageName + "." + typeName; } } /** * Convert this into a string * *@return a string representation of the type */ public String toString() { // Add the package and type names if (!isArray()) { return getLongName(); } // Start with the long name StringBuffer buffer = new StringBuffer(getLongName()); // Append the array counts for (int ndx = 0; ndx < arrayCount; ndx++) { buffer.append("[]"); } // Return the result return buffer.toString(); } /** * Provide method to visit a node * *@param visitor the visitor *@param data the data for the visit *@return some new data */ public Object accept(SummaryVisitor visitor, Object data) { return visitor.visit(this, data); } /** * Check to see if it is equal * *@param other the other item *@return true if they are equal */ public boolean equals(Object other) { if (other instanceof TypeDeclSummary) { TypeDeclSummary tds = (TypeDeclSummary) other; boolean sameType = ((typeName == null) && (tds.typeName == null)) || ((typeName != null) && typeName.equals(tds.typeName)); boolean samePackage = ((packageName == null) && (tds.packageName == null)) || ((packageName != null) && packageName.equals(tds.packageName)); boolean samePrimitive = (primitive == tds.primitive); boolean sameArray = (arrayCount == tds.arrayCount); return sameType && samePackage && samePrimitive && sameArray; } return super.equals(other); } public boolean isSame(TypeDeclSummary other) { if (primitive) { if (!other.primitive) { return false; } return typeName.equals(other.typeName); } TypeSummary type1 = GetTypeSummary.query(this); TypeSummary type2 = GetTypeSummary.query(other); return (type1 == type2); } /** * Factory method. Creates a type decl summary object from the type node. * *@param parentSummary the parent summary *@param typeNode the AST node containing the type *@return the new node */ public static TypeDeclSummary getTypeDeclSummary(Summary parentSummary, ASTType typeNode) { // Local Variables TypeDeclSummary result; Node typeChild = typeNode.jjtGetChild(0); if (typeChild instanceof ASTPrimitiveType) { result = new TypeDeclSummary(parentSummary, (ASTPrimitiveType) typeChild); } else { // if (typeChild instanceof ASTName) result = new TypeDeclSummary(parentSummary, (ASTName) typeChild); } result.setArrayCount(typeNode.getArrayCount()); return result; } /** * Factory method. Creates a type decl summary object from the type node. * *@param parentSummary the parent summary *@param typeNode the AST node containing the result type *@return the new node */ public static TypeDeclSummary getTypeDeclSummary(Summary parentSummary, ASTResultType typeNode) { if (typeNode.hasAnyChildren()) { return getTypeDeclSummary(parentSummary, (ASTType) typeNode.jjtGetChild(0)); } else { return new TypeDeclSummary(parentSummary); } } public String getName() { return toString(); } }